package cn.gemiman.daoyi.module.cms.controller.app.appsitecomment;

import cn.gemiman.daoyi.framework.common.enums.CommonStatusEnum;
import cn.gemiman.daoyi.framework.common.enums.UserTypeEnum;
import cn.gemiman.daoyi.framework.common.pojo.CommonResult;
import cn.gemiman.daoyi.framework.common.pojo.PageResult;
import cn.gemiman.daoyi.framework.common.util.object.BeanUtils;
import cn.gemiman.daoyi.framework.ratelimiter.core.annotation.RateLimiter;
import cn.gemiman.daoyi.framework.ratelimiter.core.keyresolver.impl.ClientIpRateLimiterKeyResolver;
import cn.gemiman.daoyi.framework.security.core.annotations.PreAuthenticated;
import cn.gemiman.daoyi.framework.web.core.util.WebFrameworkUtils;
import cn.gemiman.daoyi.module.cms.controller.admin.appsitecomment.vo.AppSiteCommentPageReqVO;
import cn.gemiman.daoyi.module.cms.controller.admin.appsitecomment.vo.AppSiteCommentRespVO;
import cn.gemiman.daoyi.module.cms.controller.admin.appsitecomment.vo.AppSiteCommentSaveReqVO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.appsite.AppSiteDO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.appsitecomment.AppSiteCommentDO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.appsitefootprint.AppSiteFootprintDO;
import cn.gemiman.daoyi.module.cms.service.appsite.AppSiteService;
import cn.gemiman.daoyi.module.cms.service.appsitecomment.AppSiteCommentService;
import cn.gemiman.daoyi.module.cms.service.appsitefootprint.AppSiteFootprintService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

import static cn.gemiman.daoyi.framework.common.pojo.CommonResult.success;
import static cn.gemiman.daoyi.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.gemiman.daoyi.framework.web.core.util.WebFrameworkUtils.getAppId;

@Tag(name = "用户 APP - 站点评论")
@RestController
@RequestMapping("/cms/app-site-comment")
@Validated
public class AppAppSiteCommentController {

    @Resource
    private AppSiteCommentService appSiteCommentService;
    @Resource
    private AppSiteService appSiteService;
    @Resource
    private AppSiteFootprintService appSiteFootprintService;

    @RateLimiter(count = 1, timeUnit = TimeUnit.MINUTES, keyResolver = ClientIpRateLimiterKeyResolver.class)
    @PostMapping("/create")
    @Operation(summary = "创建站点评论")
    @PreAuthenticated
    public CommonResult<Long> createAppSiteComment(@Valid @RequestBody AppSiteCommentSaveReqVO createReqVO) {
        createReqVO.setUserType(UserTypeEnum.MEMBER.getValue());
        createReqVO.setUserId(getLoginUserId());
        String appId = WebFrameworkUtils.getAppId();
        AppSiteDO appSite = appSiteService.getAppSite(appId);
        createReqVO.setAppId(appId).setAppSiteId(appSite.getId());
        return success(appSiteCommentService.createAppSiteComment(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新站点评论")
    @PreAuthenticated
    public CommonResult<Boolean> updateAppSiteComment(@Valid @RequestBody AppSiteCommentSaveReqVO updateReqVO) {
        appSiteCommentService.updateAppSiteComment(updateReqVO.setUserId(getLoginUserId()), true);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除站点评论")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthenticated
    public CommonResult<Boolean> deleteAppSiteComment(@RequestParam("id") Long id) {
        appSiteCommentService.deleteAppSiteComment(id, true);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得站点评论")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<AppSiteCommentRespVO> getAppSiteComment(@RequestParam("id") Long id) {
        AppSiteCommentDO appSiteComment = appSiteCommentService.getAppSiteComment(id);
        return success(BeanUtils.toBean(appSiteComment, AppSiteCommentRespVO.class));
    }

    @GetMapping("/getCommentTotal")
    @Operation(summary = "获取评论总条数")
    public CommonResult<Long> getAppSiteCommentTotal(@Valid AppSiteCommentPageReqVO pageReqVO) {
        pageReqVO.setAppId(getAppId());
        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        PageResult<AppSiteCommentDO> pageResult = appSiteCommentService.getAppSiteCommentPage(pageReqVO);
        return success(pageResult.getTotal());
    }

    @GetMapping("/page")
    @Operation(summary = "获得站点评论分页")
    public CommonResult<PageResult<AppSiteCommentRespVO>> getAppSiteCommentPage(@Valid AppSiteCommentPageReqVO pageReqVO) {
        pageReqVO.setAppId(getAppId());
        pageReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        pageReqVO.setParentId(ObjUtil.defaultIfNull(pageReqVO.getParentId(), 0L));
        Long parentId = pageReqVO.getParentId();
        if (parentId > 0) {
            AppSiteCommentRespVO checkedData = this.getAppSiteComment(parentId).getCheckedData();
            List<Long> parentIds = checkedData.getParentIds();
            parentIds.add(parentId);
            pageReqVO.setParentIds(CollUtil.join(parentIds, ","));
            pageReqVO.setParentId(null);
        }
        PageResult<AppSiteCommentDO> pageResult = appSiteCommentService.getAppSiteCommentPage(pageReqVO);
        PageResult<AppSiteCommentRespVO> bean = BeanUtils.toBean(pageResult, AppSiteCommentRespVO.class);
        if (parentId > 0) {
            List<AppSiteCommentRespVO> list = bean.getList();
            if (CollUtil.isNotEmpty(list)) {
                appSiteCommentService.getAppSiteCommentListBatches(list.stream().map(AppSiteCommentRespVO::getParentId).distinct().toList())
                        .parallelStream().forEach(p -> list.stream().filter(c -> c.getParentId().equals(p.getId()))
                                .parallel().forEach(c -> c.setParent(BeanUtils.toBean(p, AppSiteCommentRespVO.class)))
                        );
            }
        }
        appSiteFootprintService.generatorIsLike(UserTypeEnum.MEMBER.getValue(), getLoginUserId(), bean.getList(), AppSiteFootprintDO::getCommentId);
        return success(bean);
    }

}
